The interactive cockpit ======================== Description ---------------- The cockpit is a browser-based demonstration layer for RISE-solved models. The user manipulates the *structure that generates outcomes* --- policy-rule coefficients, regime persistence, credibility and attention, the equilibrium concept itself --- and watches the entire model economy reorganize in real time. Two constraints drive the design: 1. **Latency.** Every on-screen response to a gesture completes in well under 100 ms. Nothing is re-solved in the browser: where a feature needs solutions at many parameter values, they are precomputed on a grid and interpolated; where it needs distributions, fixed common-random-number ensembles are re-propagated or reweighted. 2. **Zero-failure demo mode.** The suite runs as a fully self-contained static page (HTML + JavaScript + precomputed binary bundles): no backend, no network, and no MATLAB session at demonstration time. The front end is *content-agnostic*: variable names, parameter names, regime labels, slider ranges and landmark rules all arrive via a manifest and per-feature data bundles exported from RISE. Swapping the model requires zero front-end changes. The system has two halves: * the **bake** (MATLAB): the ``rise.cockpit`` package solves the model, runs whatever smoothing or simulation the enabled features need, and writes ``manifest.json`` plus one binary bundle per feature; * the **front end** (JavaScript): a static single-page application in ``/cockpit/web`` that loads the bundles and runs every interaction client-side. Feature tabs appear only for bundles listed in the manifest. Features ---------------- .. list-table:: :header-rows: 1 :widths: 22 48 30 * - Tab - Interaction - Bake function * - Policy Rule Cockpit - sliders / 2-D pad on policy-rule coefficients; fans, IRFs, moments and welfare update per gesture; determinacy region masked and snapped - ``rise.cockpit.bake_policy_grid`` * - Rewriting History - shock toggles and scale sliders redraw counterfactual history and re-stack the decomposition - ``rise.cockpit.bake_history`` * - Regime Dial - transition-probability sliders and a regime paintbrush; fans go bimodal / fat-tailed as regime uncertainty rises - ``rise.cockpit.bake_regime_dial`` * - Entropic Tilting - drag any fan's median; all other fans update to the tilted distribution; effective-sample-size meter guards over-tilting - ``rise.cockpit.bake_ensemble`` * - Commitment--Discretion - one slider on the probability of commitment (loose commitment; linear-quadratic models) - ``rise.cockpit.bake_policy_grid`` with ``export_all_regimes=true`` * - Credibility / Attention - attention sliders; the response to an *announced* policy shock collapses as attention falls (forward guidance) - ``rise.cockpit.bake_policy_grid`` with ``anticipated=...`` Quick start: one call from model to browser --------------------------------------------- ``rise.cockpit.demo`` bakes every exercise its ingredients allow, writes the manifest from the model's own metadata (labels come from the model file's quoted descriptions, slider baselines from the current parameter values), starts a local server, and opens the browser: .. code-block:: matlab m = dsge_model('mymodel'); m = set(m, 'parameters', p); rise.cockpit.demo(m) The ingredients: each one you add unlocks one exercise -------------------------------------------------------- .. list-table:: :header-rows: 1 :widths: 40 25 35 * - Ingredient (option on ``demo``) - Exercise unlocked - Notes * - nothing — just the parameterized model - Entropic Tilting - drag forecast medians; always available * - ``grid=struct(phi_pi=..., phi_x=..., ...)`` — two or more rule coefficients with knot vectors - Policy Rule Cockpit - baseline = current values; must lie inside the grid * - ``grid=struct(gamma_prob=0:0.005:1)`` — a single coefficient, on a planner model with a commitment chain solved by ``loose_commitment`` - Commitment vs Discretion - see the modernized ``Canonical_plain.rs`` for the model pattern * - ``data=...`` — the observables, as the ``ts`` struct you would pass to ``filter`` - Rewriting History - one smoother pass; toggles re-weight the decomposition * - the model itself is Markov-switching - Regime Dial - automatic; ``chain_labels=`` names the states * - ``attention_grid=struct(mbar=...)`` together with ``anticipated=struct(shock=..., horizons=[4 8 12])`` - Credibility / Attention - anticipated-shock (forward guidance) IRFs baked per grid node Ingredients compose: one call with several of them bakes several tabs into the same page. To rebuild and reopen after changing something, just call ``demo`` again; ``rise.cockpit.launch(outdir)`` reopens an existing bundle without rebaking, and ``browser=false`` on either returns the URL instead of opening it. The lower-level ``bake_*`` functions remain available when you need full control over grids, welfare, landmarks, or the manifest. A complete start-to-finish walk-through lives in ``rise-modern-tutorials/Cockpit`` (``howto.m`` and ``verify.m``). The bake functions -------------------- All functions validate their inputs via ``arguments`` blocks; see each function's help text for the full reference. Highlights: ``rise.cockpit.bake_policy_grid`` Solves the model over a tensor grid of parameters. Per node it stores the (row-restricted) solution matrices, a determinacy flag, unconditional standard deviations and a quadratic welfare loss (ergodic-weighted across regimes for switching solutions), plus fixed common shock draws and the exact baseline solution for the front end's reset. Options extend the same engine to three tabs: ``anticipated=struct(shock=...,horizons=...,periods=...)`` bakes forward-guidance IRF curves per node; ``export_all_regimes=true`` additionally ships per-regime matrices and uniform draws so the front end can simulate a regime-switching process (used by the loose-commitment tab); ``name=...`` sets the bundle base name. ``rise.cockpit.bake_history`` Runs the smoother once and exports smoothed shocks, the historical decomposition and the solution matrices. Asserts two identities at bake time: the decomposition sums to smoothed history (additivity), and propagating the smoothed shocks reproduces it (P1). The level-vs-deviation convention of the decomposition is detected automatically and recorded in the meta. ``rise.cockpit.bake_regime_dial`` Exports the per-regime solutions of a Markov-switching model, the small-chain transition matrices and the composite-regime map, plus common draws for shocks and regime transitions. ``rise.cockpit.bake_ensemble`` Simulates one large baseline ensemble (default 10,000 paths) of the reported variables --- the only heavy blob in the suite; the front end reweights it live by exponential tilting. ``rise.cockpit.write_blob`` The shared binary writer: named arrays, little-endian, column-major, byte offsets recorded for the JavaScript side. Interpolation validation -------------------------- Every grid bake compares exactly solved impulse responses against multilinearly interpolated ones at random interior points and records the error distribution in the bundle meta (default acceptance: maximum relative error below 1%). Two practical caveats the validator handles: * **Never interpolate across the determinacy boundary.** A grid cell is usable only if all its corners are determinate; the front end snaps queries in unusable cells to the nearest usable cell and marks the boundary visually. * **Frontier-adjacent cells hold steep gradients by nature.** When the determinacy frontier is an interior curve that no box trimming avoids, ``validate_interior_only=true`` certifies the frontier-free interior separately and records how many frontier cells were excluded from sampling. Bundle format ---------------- Each feature ships ``.json`` (meta) and ``.bin`` (blob). The meta's ``arrays`` section maps array names to byte offsets, dtypes (``float32``, ``float64``, ``int32``, ``uint8``) and shapes in MATLAB (column-major) order; the bake writes ``A(:)`` little-endian. Grid bundles store per-node blocks contiguously, which is exactly the layout the front end's multilinear interpolator consumes. The manifest lists model metadata, variable/shock/regime labels, and one ``{bundle, meta}`` entry per enabled feature. Testing ---------------- The MATLAB side is covered in ``RISE-unit-tests`` (``models/dsge/cockpit_export/cockpitBakeTest``); the front end carries a MATLAB-free JavaScript test suite (``cd cockpit/web && node --test test/``) including integration tests that exercise a committed 250 KB fixture bundle.